#include <avr/io.h>
#include "clock.h"

uint8_t DayOfMonth[] =   { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
uint8_t DayOfMonth_f[] = {  3,  0,  3,  2,  3,  2,  3,  3,  2,  3,  2,  3 };

volatile struct_time current_time;



void init_clock (void) 
{
current_time.year=7;
current_time.month=10;
current_time.day=27;
current_time.hour=13;
current_time.min=45;
current_time.sec=0;
current_time.weekday=calc_weekday((struct_time*) &current_time);
current_time.week=calc_week((struct_time*) &current_time);
return;
}


void tick(void) {

current_time.sec++;
if (current_time.sec > 59)
{
	current_time.sec=0;
	current_time.min++;			
	if (current_time.min > 59)
	{
		current_time.min=0;			
		current_time.hour++;
		if (current_time.hour > 23)
		{
			current_time.hour=0;
			current_time.weekday++;
			if (current_time.weekday > 6)
			{
				current_time.weekday=0;
				current_time.week++;
			}
			current_time.day++;
			if ((current_time.month  == 2) && (current_time.year & 3) == 0 )  //29.Februar?
			{
	    		current_time.month++;	
			}
			else if (current_time.day > DayOfMonth[current_time.month])
			{
				current_time.day=1;
				current_time.month++;
				if (current_time.month > 12)
				{
					current_time.month=1;
					current_time.year++;
				}
			}
		}				
	}
}

}


uint8_t calc_weekday(struct_time * time) {

//http://de.wikipedia.org/wiki/Doomsday-Methode#Wochentag_des_26._Oktober_2005
//29.2.2000 = Dienstag
//1.1.2005 = Sonnabend
//uint8_t year=5;
uint8_t month=0;  // 0 = Januar
uint8_t weekday=1; //sonnabed
uint8_t temp=time->year-6; //current year - 6 years

while (temp > 4)
{
	temp-=4;
	weekday++;
}

weekday+=time->year;// + ((uint8_t) ((time->year - 6) / 4));


// wenn wir uns in einem Schaltjahr befinden und es ist nach dem 28.Feb.
if (time->month >= 1)
{
	if ((time->month == 1) && (time->day != 29));
	else 
	{
		if (!(time->year % 4 )) weekday++;  // gueltiges Schaltjahr
	}
}

while (time->month > month)
{
	weekday+=DayOfMonth_f[month];
	month++;
//	while (weekday > 6) weekday-=7;  //weekday % 7
}

// now we've got the weekday for the 1. of the current month

weekday+=(time->day-1);
while (weekday > 6) weekday-=7; // now we've got the weekday for target day

return weekday;
}

uint8_t calc_week(struct_time * time) {

struct_time  temp_time;

temp_time.year=time->year;
temp_time.month=0;  // 0 = Januar
temp_time.day=1;
uint8_t week=1;

//rechne Wochendag fuer den 1.1 des aktuellen Jahres
temp_time.weekday=calc_weekday((struct_time*) &temp_time);

while (time->month > temp_time.month)
{
	temp_time.weekday+=DayOfMonth_f[temp_time.month];
	temp_time.month++;
	week+=4;  //4 weeks per month
}

temp_time.weekday+=(time->day-1);

while (temp_time.weekday > 6)
{
	temp_time.weekday-=7;
	week++;
}


return week;
}

void set_clock(struct_time * time)
{
current_time.sec=time->sec;
current_time.min=time->min;
current_time.hour=time->hour;

current_time.day=time->day;
current_time.month=time->month;
current_time.year=time->year;

current_time.weekday=calc_weekday((struct_time*) &current_time);
current_time.week=calc_week((struct_time*)&current_time);

return;
}




struct_time* get_clock(void)
{

return(struct_time*) (&current_time);
}
